﻿using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Updating;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Xpo;
using System.Data;

namespace EasyXaf.EntityDesigner.DatabaseUpdate;

public class Updater : ModuleUpdater
{
    public Updater(IObjectSpace objectSpace, Version currentDBVersion)
        : base(objectSpace, currentDBVersion)
    {
    }

    public override void UpdateDatabaseAfterUpdateSchema()
    {
        base.UpdateDatabaseAfterUpdateSchema();

        CreateObjectTypes();
    }

    private void CreateObjectTypes()
    {
        var types = ObjectSpace.TypesInfo.PersistentTypes
            .Select(t => t.Type)
            .Where(t => typeof(PersistentBase).IsAssignableFrom(t))
            .Where(t => t.IsClass && t.IsPublic && !t.IsAbstract && !t.IsGenericType)
            .OrderBy(t => t.Assembly.FullName)
            .ThenBy(t => t.Name)
            .Select(t => new { TypeName = t.FullName, AssemblyName = t.Assembly.GetName().Name });

        foreach (var type in types)
        {
            using var connection = ((XPObjectSpace)ObjectSpace).Connection;
            connection.Open();
            using var command = connection.CreateCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = $"Select Count(*) From XPObjectType Where TypeName=@TypeName And AssemblyName=@AssemblyName";

            var typeNameParams = command.CreateParameter();
            typeNameParams.ParameterName = "@TypeName";
            typeNameParams.Value = type.TypeName;
            command.Parameters.Add(typeNameParams);

            var assemblyNameParams = command.CreateParameter();
            assemblyNameParams.ParameterName = "@AssemblyName";
            assemblyNameParams.Value = type.AssemblyName;
            command.Parameters.Add(assemblyNameParams);

            var count = (long)command.ExecuteScalar();
            if (count == 0)
            {
                command.CommandText = $"Insert Into XPObjectType (TypeName,AssemblyName) Values (@TypeName,@AssemblyName)";
                command.ExecuteNonQuery();
            }
        }
    }
}
